﻿using Collector.Device;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using Newtonsoft.Json.Linq;
using System.Runtime.InteropServices;
using Collector.Analyzer;


namespace Collector.PulseFixture
{
    class FixtureMain : GenericMold
    {
        private string TAG = "FixtureMain:";
        private FixtureCollector fixtureHandler = new FixtureCollector();
        private bool isPrepared = true;
        private bool isEnabledFixture = false;
        private string[] rawDataFile;
        private int segmentNumber = 0;
        private ProductType productType = ProductType.ePRODUCT_TYPE_SINGLE;
        // 加压mmHg门限值的最小门限系数
        private double mThresholdRatio = 0;
        private string mSegmentTargetSet;
        public bool EnabledFixture
        {
            set { isEnabledFixture = value; }
            get { return isEnabledFixture; }
        }

        ~FixtureMain()
        {
            rawDataFile = null;
        }

        public bool start()
        {
            bool ret = false;
            if (!isPrepared)
            {
                Log.Error(TAG + "No check and prepare device info.");
                return false;
            }

            ConditionWait.Reset();
#if true
            if (productType == ProductType.ePRODUCT_TYPE_THREE)
            {
                ret = threebodyparts_segmented();
            }
            else
            {
                ret = single_segmented();
            }
#endif
            if (ret)
            {
                ret = AnalyseProcessing();
                if(ret && isEnabledFixture)
                    ret = AnalyseProcessing_Fixture_test();
            }

            ConditionWait.Set();
            return ret;
        }

        public void stop()
        {
            if (isPrepared)
            {
                isPrepared = false;
                deinitialization();
                fixtureHandler.stop();                
            }
        }

        public void startAsync()
        {
            Thread nth = new Thread(() =>
            {
                start();
            });

            nth.Start();
        }

        public bool prepared(double thresholdRatio, string targetList, ProductType type)
        {
            isPrepared = initialization();
            if(isPrepared)
            {
                isPrepared = checkAndPreparedDeviceInfo();
                if(!isPrepared)
                {
                    // release pulse device resource
                    deinitialization();
                }
            }

            if(isPrepared && isEnabledFixture)
            {
                // init fixture device
                fixtureHandler.setFixtureDataDeliver(fixtureDataProcessing);
                fixtureHandler.DeviceSerialNumber = DeviceSerialNumber;
                // Pa
                fixtureHandler.Baseline = (int)Baselines[0] * 100;
                isPrepared = fixtureHandler.run();
                if(!isPrepared)
                {
                    // release pulse device resource
                    deinitialization();
                }
            }

            mThresholdRatio = thresholdRatio;
            mSegmentTargetSet = targetList;
            productType = type;

            return isPrepared;
        }

        private bool threebodyparts_segmented()
        {
            PulseCommonHelper.Display display = new PulseCommonHelper.Display();

            // 将分段压力值转换成int
            List<int> mmHgListInfo = mSegmentTargetSet.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(Int32.Parse).ToList();

            // 创建三部基线压力
            Dictionary<BodyPart, double> baseLineMap = new Dictionary<BodyPart, double>
            {
                {BodyPart.eBODY_PART_CUN, Baselines[0]*100.0 },
                {BodyPart.eBODY_PART_GUAN, Baselines[1]*100.0 },
                {BodyPart.eBODY_PART_CHI, Baselines[2]*100.0 }
            };

            if (isEnabledFixture)
            {
                fixtureHandler.SegmentMaxCount = mmHgListInfo.Count();
                fixtureHandler.SegmentCurrentIndex = 0;
            }

            // 创建分段对象
            PulseThreeBodyPartsSegmentCollector PSProcessing = new PulseThreeBodyPartsSegmentCollector(baseLineMap, mmHgListInfo);
            SerialPort.SerialPort.collector = PSProcessing;
            PSProcessing.DeviceCommunication = DCManager;
            PSProcessing.notifyMainForm += new CollectorUINotifyHandler<PulseCommonHelper.Display>(CollectorUINotify);
            PSProcessing.ThresholdRadio = mThresholdRatio;
            PSProcessing.RawDataPath = null;
            PSProcessing.AddObserver(collectorChangeState);

            // Write pulse data to file.
            PSProcessing.UserRightHandSel = false;
            PSProcessing.PhoneNumber = "00000000000";
            PSProcessing.SerialNumber = DeviceSerialNumber;
            PSProcessing.RawDataPath = Application.StartupPath + "\\PulseData\\Segment";
            
            bool ret = PSProcessing.DoSubsectionProcessing();
            if (ret)
            {
                display.Message = "分段加压测试 PASS";
                display.LogLevel = LogMsgType.INFO;
                notifyMessage(display, PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_MSG);
                segmentNumber = mmHgListInfo.Count;
                //rawDataFile = new string[segmentNumber];
                rawDataFile = PSProcessing.RawDataFile;

                // 开始泄压
                display.Message = "开始泄压复位设备...";
                display.LogLevel = LogMsgType.INFO;
                notifyMessage(display, PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_MSG);
                // 请求复位设备
                ret = PSProcessing.ResetDevice();

                // 泄压结束
                display.Message = ret ? "泄压复位设备完成" : "自动泄压 Fail";
                display.LogLevel = ret ? LogMsgType.INFO : LogMsgType.ERROR;
                notifyMessage(display, PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_MSG);

                return ret;
            }
            else
            {
                display.Message = "分段加压测试 Fail";
                display.LogLevel = LogMsgType.ERROR;
                notifyMessage(display, PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_MSG);
                
                // 开始泄压
                display.Message = "开始泄压复位设备...";
                display.LogLevel = LogMsgType.INFO;
                notifyMessage(display, PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_MSG);

                // 请求复位设备
                ret = PSProcessing.ResetDevice();

                // 泄压结束
                display.Message = ret ? "泄压复位设备完成" : "自动泄压 Fail";
                display.LogLevel = ret ? LogMsgType.INFO : LogMsgType.ERROR;
                notifyMessage(display, PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_MSG);

                return false;
            }
        }

        private bool single_segmented()
        {
            PulseCommonHelper.Display display = new PulseCommonHelper.Display();
            // 将分段压力值转换成int
            List<int> mmHgListInfo = mSegmentTargetSet.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(Int32.Parse).ToList();
            
            if (isEnabledFixture)
            {
                fixtureHandler.SegmentMaxCount = mmHgListInfo.Count();
                fixtureHandler.SegmentCurrentIndex = 0;
            }

            // 创建分段对象
            PulseSingleSegmentCollector PSProcessing = new PulseSingleSegmentCollector(Baselines[0], mmHgListInfo);
            SerialPort.SerialPort.collector = PSProcessing;
            PSProcessing.DeviceCommunication = DCManager;
            PSProcessing.notifyMainForm += new CollectorUINotifyHandler<PulseCommonHelper.Display>(CollectorUINotify);
            PSProcessing.ThresholdRadio = mThresholdRatio;
            PSProcessing.RawDataPath = null;
            PSProcessing.AddObserver(collectorChangeState);

            // 治具默认存储数据
            PSProcessing.UserRightHandSel = false;
            PSProcessing.PhoneNumber = "00000000000";
            PSProcessing.SerialNumber = DeviceSerialNumber;
            PSProcessing.RawDataPath = Application.StartupPath + "\\PulseData\\Segment";

            bool ret = PSProcessing.DoSubsectionProcessing();
            if (ret)
            {
                display.Message = "分段加压测试 PASS";
                display.LogLevel = LogMsgType.INFO;
                notifyMessage(display, PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_MSG);
                segmentNumber = mmHgListInfo.Count;
                //rawDataFile = new string[segmentNumber];
                rawDataFile = PSProcessing.RawDataFile;

                // 开始泄压
                display.Message = "开始泄压复位设备...";
                display.LogLevel = LogMsgType.INFO;
                notifyMessage(display, PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_MSG);

                // 请求复位设备
                ret = PSProcessing.ResetDevice();

                // 泄压结束
                display.Message = ret ? "泄压复位设备完成" : "自动泄压 Fail";
                display.LogLevel = ret ? LogMsgType.INFO : LogMsgType.ERROR;
                notifyMessage(display, PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_MSG);
                return ret;
            }
            else
            {
                display.Message = "分段加压测试 Fail";
                display.LogLevel = LogMsgType.ERROR;
                notifyMessage(display, PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_MSG);

                // 开始泄压
                display.Message = "开始泄压复位设备...";
                display.LogLevel = LogMsgType.INFO;
                notifyMessage(display, PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_MSG);

                // 请求复位设备
                ret = PSProcessing.ResetDevice();
                // 开始泄压
                display.Message = ret ? "泄压复位设备完成" : "自动泄压 Fail";
                display.LogLevel = ret? LogMsgType.INFO:LogMsgType.ERROR;
                notifyMessage(display, PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_MSG);

                return false;
            }          
        }

        private void fixtureDataProcessing(double value, int type)
        {
            if (State == CollectorState.eCOLLECTOR_STATE_COMPLETED)
                return;

            PulseCommonHelper.Display display = new PulseCommonHelper.Display();
            FixtureData fixtureData = new FixtureData(value, type);
            CollectorIntention intent = new CollectorIntention();
            intent.Data = (object)fixtureData;
            intent.Type = CollectorIntention.IntentionType.eINTENT_TYPE_UPDATA_FIXTURE_PRESSURE;
            display.UserData = intent;
            
            notifyMessage(display, PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_USER);
        }

        private void collectorChangeState(CollectorState state, int product)
        {
            if(isEnabledFixture)
                fixtureHandler.setCollectorState(state, product);
            State = state;
        }

        private bool AnalyseProcessing()
        {
            int[] segmentSizes = new int[segmentNumber];
            IntPtr handler = Analyzer.IAnalyzer.create_handler(segmentNumber, (int)Baselines[0], (int)Baselines[1], (int)Baselines[2], 0);
            if (handler == null)
            {
                Log.Debug(TAG + "Create analyzer handler is failed.");
                return false;
            }

            Log.Debug(TAG + "start fill data...");
            for (int i = 0; i < segmentNumber; i++)
            {
                byte[] data = Analyzer.AnalyzerFileStream.ReadBytes(rawDataFile[i]);
                segmentSizes[i] = data.Length;
                Log.Debug(TAG + "fill frame data size:{0}", data.Length);

                // using IntPtr pass buffer
#if false
                //分配结构体大小的内存空间
                IntPtr structPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(data.Length);
                //将byte数组拷到分配好的内存空间
                System.Runtime.InteropServices.Marshal.Copy(data, 0, structPtr, data.Length);
#endif
                UInt32 header = BitConverter.ToUInt32(data, 0);
                if (header == IDeviceProtocolShape.PULSE_FRAME_HEADER)
                {
                    int framesize = data[IDeviceProtocolShape.FRAME_FIELD_LENGTH_OFFSET] + 5;
                    Analyzer.IAnalyzer.fill_frame_package(handler, data, framesize, data.Length / framesize, i);
                }
#if false
                //释放内存空间
                System.Runtime.InteropServices.Marshal.FreeHGlobal(structPtr);
#endif
            }


            StringBuilder retpara = new StringBuilder(6);
            Log.Debug(TAG + "start analyzing data...");
            IntPtr result = Analyzer.IAnalyzer.analyzing_data(handler, retpara, 6);
            if (result == null)
            {
                return false;
            }

            Analyzer.IAnalyzer.PulseResult pulse_result = (Analyzer.IAnalyzer.PulseResult)Marshal.PtrToStructure(result, typeof(Analyzer.IAnalyzer.PulseResult));

            Log.Debug(string.Format("脉诊仪 算法分析结果,长度:{0} - {1}, 结果:*{2}**", pulse_result.lengths, pulse_result.Data.Length, pulse_result.Data), LogMsgType.INFO);

            Log.Debug(TAG + "jobject parse json");
            JObject pulseRst = JObject.Parse(pulse_result.Data);            
            Log.Debug("json format :" + pulseRst.ToString());

            IAnalyzer.free_pulse_result(result);
            IAnalyzer.release_handler(handler);

            string jsonKey;
            foreach (JToken child in pulseRst.Children())
            {
                PulseCommonHelper.Display display = new PulseCommonHelper.Display();
                string winer = "";
                jsonKey = child.Path.ToString();
                Log.Debug("jsonKey :" + pulseRst[jsonKey]["res"].ToString());
                if (jsonKey == "cun")
                {
                    string outputSeq = pulseRst[jsonKey]["res"]["OutputSeq"].ToString();
                    if(string.IsNullOrWhiteSpace(outputSeq))
                    {
                        Log.Debug(TAG + "NO found output seq : " + jsonKey);
                        continue;
                    }
                    winer = pulseRst[jsonKey][outputSeq].ToString();

                }
                else if (jsonKey == "guan")
                {
                    string outputSeq = pulseRst[jsonKey]["res"]["OutputSeq"].ToString();
                    if (string.IsNullOrWhiteSpace(outputSeq))
                    {
                        Log.Debug(TAG + "NO found output seq : " + jsonKey);
                        continue;
                    }
                    winer = pulseRst[jsonKey][outputSeq].ToString();
                }
                else if (jsonKey == "chi")
                {
                    string outputSeq = pulseRst[jsonKey]["res"]["OutputSeq"].ToString();
                    if (string.IsNullOrWhiteSpace(outputSeq))
                    {
                        Log.Debug(TAG + "NO found output seq : " + jsonKey);
                        continue;
                    }
                    winer = pulseRst[jsonKey][outputSeq].ToString();
                }

                CollectorIntention intent = new CollectorIntention();
                intent.Message = winer;
                intent.ResultType = jsonKey;
                intent.Type = CollectorIntention.IntentionType.eINTENT_TYPE_UPDATA_PULSE_RESULT;
                display.Message = jsonKey;
                display.UserData = intent;
                notifyMessage(display, PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_USER);
            }

            return true;
        }

        private bool AnalyseProcessing_file_test()
        {
            byte[] pingpong1 = new byte[0], pingpong2 = new byte[0];
            int[] segmentSizes = new int[3];
            bool swap = false;

            rawDataFile = new string[3];
#if false
            rawDataFile[0] =
                "F:\\work\\huaan\\PulseDeviceCollector\\Collector\\bin\\Debug\\PulseData\\Segment\\GMMX-00000000000-3-003255151565535-20250312-183710973-104164-104271-104416-L.dat";
            rawDataFile[1] =
                "F:\\work\\huaan\\PulseDeviceCollector\\Collector\\bin\\Debug\\PulseData\\Segment\\GMMX-00000000000-3-003255151565535-20250312-183726629-104164-104271-104416-L.dat";
            rawDataFile[2] =
                "F:\\work\\huaan\\PulseDeviceCollector\\Collector\\bin\\Debug\\PulseData\\Segment\\GMMX-00000000000-3-003255151565535-20250312-183744605-104164-104271-104416-L.dat";
#else
            rawDataFile[0] = "F:\\work\\huaan\\test-proj\\testData\\GMMX-00000000000-3-003255151565535-20250317-103432547-107006-106852-106332-L.dat";
            rawDataFile[1] = "F:\\work\\huaan\\test-proj\\testData\\GMMX-00000000000-3-003255151565535-20250317-103503080-107006-106852-106332-L.dat";
            rawDataFile[2] = "F:\\work\\huaan\\test-proj\\testData\\GMMX-00000000000-3-003255151565535-20250317-103533610-107006-106852-106332-L.dat";
#endif

            Log.Debug(TAG + "start Create analyzer handler.");
            IntPtr handler;
            handler = Analyzer.IAnalyzer.create_handler(3, 107006, 106852, 106332, 0);
            Log.Debug(TAG + "start Create analyzer handler---.");
            //return false;

            if (handler == null)
            {
                Log.Debug(TAG + "Create analyzer handler is failed.");
                return false;
            }

            Log.Debug(TAG + "start fill data...");
            for (int i=0; i< 3; i++)
            {
                byte[] data = Analyzer.AnalyzerFileStream.ReadBytes(rawDataFile[i]);
                segmentSizes[i] = data.Length;
                Log.Debug(TAG + "start fill data"); 
                Analyzer.IAnalyzer.fill_frame_package(handler, data, 17, data.Length/17, i);
            }


            StringBuilder retpara = new StringBuilder(6);
            Log.Debug(TAG + "start analyzing data...");
            IntPtr result = Analyzer.IAnalyzer.analyzing_data(handler, retpara, 6);
            if (result == null)
            {
                return false;
            }

            Analyzer.IAnalyzer.PulseResult pulse_result = (Analyzer.IAnalyzer.PulseResult)Marshal.PtrToStructure(result, typeof(Analyzer.IAnalyzer.PulseResult));

            //Log.Debug(string.Format("脉诊仪 算法分析结果,长度:{0} - {1}, 结果:*{2}**", pulse_result.lengths, pulse_result.Data.Length, pulse_result.Data), LogMsgType.INFO);

            JObject pulseRst = JObject.Parse(pulse_result.Data);
            Log.Debug("json format :" + pulseRst.ToString());

            IAnalyzer.free_pulse_result(result);
            IAnalyzer.release_handler(handler);
            string jsonKey;
            foreach (JToken child in pulseRst.Children())
            {
                PulseCommonHelper.Display display = new PulseCommonHelper.Display();
                string winer = "";
                jsonKey = child.Path.ToString();
                Log.Debug("jsonKey :" + pulseRst[jsonKey]["res"].ToString());
                if (jsonKey == "cun")
                {
                    string outputSeq = pulseRst[jsonKey]["res"]["OutputSeq"].ToString();
                    winer = pulseRst[jsonKey][outputSeq].ToString();

                } else if(jsonKey == "guan")
                {
                    string outputSeq = pulseRst[jsonKey]["res"]["OutputSeq"].ToString();
                    winer = pulseRst[jsonKey][outputSeq].ToString();
                } else if(jsonKey == "chi")
                {
                    string outputSeq = pulseRst[jsonKey]["res"]["OutputSeq"].ToString();
                    winer = pulseRst[jsonKey][outputSeq].ToString();
                }
                
                CollectorIntention intent = new CollectorIntention();
                intent.Message = winer;
                intent.ResultType = jsonKey;
                intent.Type = CollectorIntention.IntentionType.eINTENT_TYPE_UPDATA_PULSE_RESULT;
                display.Message = jsonKey;
                display.UserData = intent;
                notifyMessage(display, PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_USER);
            }
            
            return true;
        }

        private bool AnalyseProcessing_old_single_test()
        {
            segmentNumber = 3;
            byte[] pingpong1 = new byte[0], pingpong2 = new byte[0];
            int[] segmentSizes = new int[segmentNumber];
            bool swap = false;
            rawDataFile = new string[segmentNumber];
            rawDataFile[0] =
                "F:\\work\\huaan\\PulseDeviceCollector\\Collector\\bin\\Debug\\PulseData\\Segment\\GMMX-00000000000-3-002255151565535-20250313-204957152-101325-L.dat";
            rawDataFile[1] =
                "F:\\work\\huaan\\PulseDeviceCollector\\Collector\\bin\\Debug\\PulseData\\Segment\\GMMX-00000000000-3-002255151565535-20250313-205009597-101325-L.dat";
            rawDataFile[2] =
                "F:\\work\\huaan\\PulseDeviceCollector\\Collector\\bin\\Debug\\PulseData\\Segment\\GMMX-00000000000-3-002255151565535-20250313-205021137-101325-L.dat";

            for (int i = 0; i < segmentNumber; i++)
            {
                byte[] data = Analyzer.AnalyzerFileStream.ReadBytes(rawDataFile[i]);
                segmentSizes[i] = data.Length;
                if (swap ^ true)
                {
                    swap = true;
                    pingpong1 = new byte[data.Length + pingpong2.Length];
                    Array.Copy(pingpong2, 0, pingpong1, 0, pingpong2.Length);
                    Array.Copy(data, 0, pingpong1, pingpong2.Length, data.Length);
                }
                else
                {
                    swap = false;
                    pingpong2 = new byte[data.Length + pingpong1.Length];
                    Array.Copy(pingpong2, 0, pingpong1, 0, pingpong1.Length);
                    Array.Copy(data, 0, pingpong2, pingpong1.Length, data.Length);
                }
            }

            WaveParamStc wave_parame = new WaveParamStc()
            {
                SBaseLine = 102000,
                SamplingFrq = 100,
                mmHg_to_g = (float)1.67,
                g_to_mmHg = (float)0.6
            };

            StringBuilder retpara = new StringBuilder(63000);
            Analyzer.IAnalyzer.AnalysePulseWithMultichannelOut(ref wave_parame, (swap ? pingpong1 : pingpong2), segmentSizes, retpara, 0);
            Log.Debug(string.Format("{0},算法分析结果:{1}", "脉诊仪", retpara.ToString()), LogMsgType.INFO);
            if (string.IsNullOrWhiteSpace(retpara.ToString()) || (retpara.ToString() == "{}") ||
                retpara.ToString().Contains("error type"))
            {
                return false;
            }

            JObject pulseRst = JObject.Parse(retpara.ToString());
            Log.Debug("pulseRst :" + pulseRst.ToString());

            return true;
        }

        private bool AnalyseProcessin_old_file()
        {
            byte[] pingpong1 = new byte[0], pingpong2 = new byte[0];
            int[] segmentSizes = new int[segmentNumber];
            bool swap = false;
            for (int i = 0; i < segmentNumber; i++)
            {
                byte[] data = Analyzer.AnalyzerFileStream.ReadBytes(rawDataFile[i]);
                segmentSizes[i] = data.Length;
                if (swap ^ true)
                {
                    swap = true;
                    pingpong1 = new byte[data.Length + pingpong2.Length];
                    Array.Copy(pingpong2, 0, pingpong1, 0, pingpong2.Length);
                    Array.Copy(data, 0, pingpong1, pingpong2.Length, data.Length);
                }
                else
                {
                    swap = false;
                    pingpong2 = new byte[data.Length + pingpong1.Length];
                    Array.Copy(pingpong2, 0, pingpong1, 0, pingpong1.Length);
                    Array.Copy(data, 0, pingpong2, pingpong1.Length, data.Length);
                }
            }

            WaveParamStc wave_parame = new WaveParamStc()
            {
                SBaseLine = 102000,
                SamplingFrq = 100,
                mmHg_to_g = (float)1.67,
                g_to_mmHg = (float)0.6
            };

            StringBuilder retpara = new StringBuilder(63000);
            Analyzer.IAnalyzer.AnalysePulseWithMultichannelOut(ref wave_parame, (swap ? pingpong1 : pingpong2), segmentSizes, retpara, 0);
            Log.Debug(string.Format("{0},算法分析结果:{1}", "脉诊仪", retpara.ToString()), LogMsgType.INFO);
            if (string.IsNullOrWhiteSpace(retpara.ToString()) || (retpara.ToString() == "{}") ||
                retpara.ToString().Contains("error type"))
            {
                return false;
            }

            JObject pulseRst = JObject.Parse(retpara.ToString());
            Log.Debug("pulseRst :" + pulseRst.ToString());

            return true;
        }

        /// ////////////////////////////////////////////////////
        private bool AnalyseProcessing_Fixture_test()
        {
            byte[] pingpong1 = new byte[0], pingpong2 = new byte[0];
            int[] segmentSizes = new int[] { 0, 0, 0};
            bool swap = false;

            Log.Debug(TAG + "segmentNumber: {0}", segmentNumber);
            for (int i = 0; i < segmentNumber; i++)
            {
                byte[] data = Analyzer.AnalyzerFileStream.ReadBytes(fixtureHandler.DAQAI0RecordFile[i]);
                segmentSizes[i] = data.Length;
                Log.Debug(TAG + "segment size: {0}", data.Length);
                if (swap ^ true)
                {
                    swap = true;
                    pingpong1 = new byte[data.Length + pingpong2.Length];
                    Array.Copy(pingpong2, 0, pingpong1, 0, pingpong2.Length);
                    Array.Copy(data, 0, pingpong1, pingpong2.Length, data.Length);
                }
                else
                {
                    swap = false;
                    pingpong2 = new byte[data.Length + pingpong1.Length];
                    Array.Copy(pingpong2, 0, pingpong1, 0, pingpong1.Length);
                    Array.Copy(data, 0, pingpong2, pingpong1.Length, data.Length);
                }
            }

            WaveParamStc wave_parame = new WaveParamStc()
            {
                SBaseLine = (int)Baselines[0],
                SamplingFrq = 100,
                mmHg_to_g = (float)1.67,
                g_to_mmHg = (float)0.6
            };

            StringBuilder retpara = new StringBuilder(63000);
            Analyzer.IAnalyzer.AnalysePulseWithMultichannelOut(ref wave_parame, (swap ? pingpong1 : pingpong2), segmentSizes, retpara, 0);
            Log.Debug(string.Format("{0},算法分析结果:{1}", "脉诊仪", retpara.ToString()), LogMsgType.INFO);
            if (string.IsNullOrWhiteSpace(retpara.ToString()) || (retpara.ToString() == "{}") ||
                retpara.ToString().Contains("error type"))
            {
                return false;
            }

            string jsonKey = "";
            JObject pulseRst = JObject.Parse(retpara.ToString());
            Log.Debug("pulseRst :" + pulseRst.ToString());
            foreach (JToken child in pulseRst.Children())
            {
                jsonKey = child.Path.ToString();
                Log.Debug("jsonKey :" + jsonKey);
            }

            PulseCommonHelper.Display display = new PulseCommonHelper.Display();
            CollectorIntention intent = new CollectorIntention();
            intent.Message = pulseRst[jsonKey].ToString();
            intent.ResultType = jsonKey;
            intent.Type = CollectorIntention.IntentionType.eINTENT_TYPE_UPDATA_FIXTURE_RESULT;
            display.Message = jsonKey;
            display.UserData = intent;
            notifyMessage(display, PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_USER);

#if false
            //脉诊治具波形数据算法结果
            BeginInvoke(new Action(() =>
            {
                this.label_fixture_PulseName.Text = PulseParser.AnalysePulseName(pulseRst[jsonKey]["m_PulseRst"]["PulseName"].ToString());
                this.label_fixture_Position.Text = PulseParser.AnalysePulsePosition(pulseRst[jsonKey]["m_PulseRst"]["PulsePosition"].ToString()).Split(' ')[0];
                this.label_fixture_PulseForce.Text = PulseParser.AnalysePulseForce(pulseRst[jsonKey]["m_PulseRst"]["PulseForce"].ToString());
                this.label_fixture_PulseRate.Text = PulseParser.AnalysePulseRate(pulseRst[jsonKey]["m_PulseRst"]["PulseRate"].ToString());
                this.label_fixture_Rhythm.Text = PulseParser.AnalysePulseRhythm(pulseRst[jsonKey]["m_PulseRst"]["Rhythm"].ToString());
                this.label_fixture_Tension.Text = PulseParser.AnalysePulsePotential(pulseRst[jsonKey]["m_PulseRst"]["PulseTension"].ToString(), true);
                this.label_fixture_Fluency.Text = PulseParser.AnalysePulsePotential(pulseRst[jsonKey]["m_PulseRst"]["PulseFluency"].ToString(), false);

                double mul = Convert.ToDouble(pulseRst[jsonKey]["m_WaveRst"]["h1"].ToString()) / cun_h1;
                double h1 = Convert.ToDouble(pulseRst[jsonKey]["m_WaveRst"]["h1"].ToString()) / (mul - 1);
                Log.Debug(TAG + "mul:{0} cun_h1:{1} h1:{2}", mul, cun_h1, h1);

                this.label_fixture_h1.Text = Math.Round(h1, 2).ToString();
                this.label_fixture_t.Text = pulseRst[jsonKey]["m_WaveRst"]["t"].ToString();
                this.label_fixture_t1.Text = pulseRst[jsonKey]["m_WaveRst"]["t1"].ToString();

                double h3_h1 = (double)pulseRst[jsonKey]["m_WaveRst"]["h3"] / (double)pulseRst[jsonKey]["m_WaveRst"]["h1"];
                double h5_h1 = (double)pulseRst[jsonKey]["m_WaveRst"]["h5"] / (double)pulseRst[jsonKey]["m_WaveRst"]["h1"];

                this.label_fixture_h3_h1.Text = Math.Round(Math.Abs(h3_h1), 3).ToString();
                this.label_fixture_h5_h1.Text = Math.Round(Math.Abs(h5_h1), 3).ToString();

                List<double> H1Value = FileConfig.getmmHgList("H1ThresholdValue").
                   Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(Double.Parse).ToList();
                double threValue = Math.Abs(Math.Round((cun_h1 / h1), 2));
                this.ShowMsg(string.Format("Result:{0}%", threValue), LogMsgType.INFO);

                BeginInvoke(new Action(() =>
                {
                    this.label_result.Visible = true;
                    this.label_result_value.Visible = true;
                }));

                if (threValue <= H1Value[1])
                {
                    this.label_result_value.Invoke(new EventHandler(delegate
                    {
                        this.label_result_value.BackColor = Color.Green;
                        this.label_result_value.Text = string.Format("{0}%", threValue);
                    }));
                    this.ShowInfo("PASS", Color.Green);
                }
                else
                {
                    this.label_result_value.Invoke(new EventHandler(delegate
                    {
                        this.label_result_value.BackColor = Color.Red;
                        this.label_result_value.Text = string.Format("{0}%", threValue);
                    }));

                    this.ShowInfo("FAIL", Color.Red);
                }
            }));
#endif
            return true;
        }

        private int CollectorUINotify(PulseCommonHelper.Display obj, PulseCommonHelper.Display.DisplayType type)
        {
            notifyMessage(obj, type);
            return 0;
        }

        public class FixtureData
        {
            private double pressure;
            int type;

            public FixtureData(double value, int type)
            {
                this.pressure = value;
                this.type = type;
            }

            public double Pressure
            {
                get { return pressure; }
                set { pressure = value; }
            }

            public int Type
            {
                get { return type; }
                set { type = value; }
            }
        }
    }
}
